/******************************************************************************* * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Martin Karpisek (martin.karpisek@gmail.com) - bug 229474 *******************************************************************************/ package org.eclipse.ant.internal.ui.launchConfigurations; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.ant.internal.ui.AntUIImages; import org.eclipse.ant.internal.ui.AntUIPlugin; import org.eclipse.ant.internal.ui.AntUtil; import org.eclipse.ant.internal.ui.IAntUIConstants; import org.eclipse.ant.internal.ui.IAntUIHelpContextIds; import org.eclipse.ant.internal.ui.model.AntElementNode; import org.eclipse.ant.internal.ui.model.AntModelContentProvider; import org.eclipse.ant.internal.ui.model.AntProjectNode; import org.eclipse.ant.internal.ui.model.AntTargetNode; import org.eclipse.ant.internal.ui.model.InternalTargetFilter; import org.eclipse.ant.launching.IAntLaunchConstants; import org.eclipse.core.externaltools.internal.IExternalToolConstants; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import com.ibm.icu.text.MessageFormat; /** * Launch configuration tab which allows the user to choose the targets from an Ant buildfile that will be executed when the configuration is * launched. */ public class AntTargetsTab extends AbstractLaunchConfigurationTab { private AntTargetNode fDefaultTarget = null; private AntTargetNode[] fAllTargets = null; private List<AntTargetNode> fOrderedTargets = null; private CheckboxTableViewer fTableViewer = null; private Label fSelectionCountLabel = null; private Text fTargetOrderText = null; private Button fOrderButton = null; private Button fFilterInternalTargets; private InternalTargetFilter fInternalTargetFilter = null; private Button fSortButton; private ILaunchConfiguration fLaunchConfiguration; private int fSortDirection = 0; private boolean fInitializing = false; /** * Sort direction constants. */ public final static int SORT_NONE = 0; public final static int SORT_NAME = 1; public final static int SORT_NAME_REVERSE = -1; public final static int SORT_DESCRIPTION = 2; public final static int SORT_DESCRIPTION_REVERSE = -2; /** * A comparator which can sort targets by name or description, in forward or reverse order. */ private class AntTargetsComparator extends ViewerComparator { /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public int compare(Viewer viewer, Object e1, Object e2) { if (!(e1 instanceof AntTargetNode && e2 instanceof AntTargetNode)) { return super.compare(viewer, e1, e2); } if (fSortDirection == SORT_NONE) { return 0; } String string1, string2; int result = 0; if (fSortDirection == SORT_NAME || fSortDirection == SORT_NAME_REVERSE) { string1 = ((AntTargetNode) e1).getLabel(); string2 = ((AntTargetNode) e2).getLabel(); } else { string1 = ((AntTargetNode) e1).getTarget().getDescription(); string2 = ((AntTargetNode) e2).getTarget().getDescription(); } if (string1 != null && string2 != null) { result = getComparator().compare(string1, string2); } else if (string1 == null) { result = 1; } else if (string2 == null) { result = -1; } if (fSortDirection < 0) { // reverse sort if (result == 0) { result = -1; } else { result = -result; } } return result; } } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl(Composite parent) { Font font = parent.getFont(); Composite comp = new Composite(parent, SWT.NONE); setControl(comp); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IAntUIHelpContextIds.ANT_TARGETS_TAB); GridLayout topLayout = new GridLayout(); comp.setLayout(topLayout); GridData gd = new GridData(GridData.FILL_BOTH); comp.setLayoutData(gd); comp.setFont(font); createTargetsTable(comp); createSelectionCount(comp); Composite buttonComposite = new Composite(comp, SWT.NONE); GridLayout layout = new GridLayout(); layout.verticalSpacing = 0; layout.marginHeight = 0; layout.marginWidth = 0; buttonComposite.setLayout(layout); buttonComposite.setFont(font); createSortTargets(buttonComposite); createFilterInternalTargets(buttonComposite); createVerticalSpacer(comp, 1); createTargetOrder(comp); Dialog.applyDialogFont(parent); } /** * Creates the selection count widget * * @param parent * the parent composite */ private void createSelectionCount(Composite parent) { fSelectionCountLabel = new Label(parent, SWT.NONE); fSelectionCountLabel.setFont(parent.getFont()); fSelectionCountLabel.setText(AntLaunchConfigurationMessages.AntTargetsTab_0_out_of_0_selected_2); GridData gd = new GridData(GridData.FILL_HORIZONTAL); fSelectionCountLabel.setLayoutData(gd); } /** * Creates the widgets that display the target order * * @param parent * the parent composite */ private void createTargetOrder(Composite parent) { Font font = parent.getFont(); Label label = new Label(parent, SWT.NONE); label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Target_execution_order__3); label.setFont(font); Composite orderComposite = new Composite(parent, SWT.NONE); GridData gd = new GridData(GridData.FILL_HORIZONTAL); orderComposite.setLayoutData(gd); GridLayout layout = new GridLayout(2, false); layout.marginHeight = 0; layout.marginWidth = 0; orderComposite.setLayout(layout); orderComposite.setFont(font); fTargetOrderText = new Text(orderComposite, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); fTargetOrderText.setFont(font); gd = new GridData(GridData.FILL_HORIZONTAL); gd.heightHint = 40; gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; fTargetOrderText.setLayoutData(gd); fOrderButton = createPushButton(orderComposite, AntLaunchConfigurationMessages.AntTargetsTab__Order____4, null); gd = (GridData) fOrderButton.getLayoutData(); gd.verticalAlignment = GridData.BEGINNING; fOrderButton.setFont(font); fOrderButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleOrderPressed(); } }); } /** * Creates the toggle to filter internal targets from the table * * @param parent * the parent composite */ private void createFilterInternalTargets(Composite parent) { fFilterInternalTargets = createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_12); fFilterInternalTargets.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleFilterTargetsSelected(); } }); } /** * Creates the toggle to sort targets in the table * * @param parent * the parent composite */ private void createSortTargets(Composite parent) { fSortButton = createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_14); fSortButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleSortTargetsSelected(); } }); } /** * The filter targets button has been toggled. If it's been turned on, filter out internal targets. Else, restore internal targets to the table. */ private void handleFilterTargetsSelected() { boolean filter = fFilterInternalTargets.getSelection(); if (filter) { fTableViewer.addFilter(getInternalTargetsFilter()); } else { fTableViewer.removeFilter(getInternalTargetsFilter()); } // Must refresh before updating selection count because the selection // count's "hidden" reporting needs the content provider to be queried // first to count how many targets are hidden. updateSelectionCount(); if (!fInitializing) { updateLaunchConfigurationDialog(); } } private ViewerFilter getInternalTargetsFilter() { if (fInternalTargetFilter == null) { fInternalTargetFilter = new InternalTargetFilter(); } return fInternalTargetFilter; } /** * The button to sort targets has been toggled. Set the tab's sorting as appropriate. */ private void handleSortTargetsSelected() { setSort(fSortButton.getSelection() ? SORT_NAME : SORT_NONE); } /** * Sets the sorting of targets in this tab. See the sort constants defined above. * * @param column * the column which should be sorted on */ private void setSort(int column) { fSortDirection = column; fTableViewer.refresh(); if (!fInitializing) { updateLaunchConfigurationDialog(); } } /** * The target order button has been pressed. Prompt the user to reorder the selected targets. */ private void handleOrderPressed() { TargetOrderDialog dialog = new TargetOrderDialog(getShell(), fOrderedTargets.toArray(new AntTargetNode[fOrderedTargets.size()])); int ok = dialog.open(); if (ok == Window.OK) { fOrderedTargets.clear(); Object[] targets = dialog.getTargets(); for (int i = 0; i < targets.length; i++) { fOrderedTargets.add((AntTargetNode) targets[i]); updateSelectionCount(); updateLaunchConfigurationDialog(); } } } /** * Creates the table which displays the available targets * * @param parent * the parent composite */ private void createTargetsTable(Composite parent) { Font font = parent.getFont(); Label label = new Label(parent, SWT.NONE); label.setFont(font); label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Check_targets_to_e_xecute__1); final Table table = new Table(parent, SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION); GridData data = new GridData(GridData.FILL_BOTH); int availableRows = availableRows(parent); data.heightHint = table.getItemHeight() * (availableRows / 20); data.widthHint = 250; table.setLayoutData(data); table.setFont(font); table.setHeaderVisible(true); table.setLinesVisible(true); TableLayout tableLayout = new TableLayout(); ColumnWeightData weightData = new ColumnWeightData(30, true); tableLayout.addColumnData(weightData); weightData = new ColumnWeightData(70, true); tableLayout.addColumnData(weightData); table.setLayout(tableLayout); final TableColumn column1 = new TableColumn(table, SWT.NULL); column1.setText(AntLaunchConfigurationMessages.AntTargetsTab_Name_5); final TableColumn column2 = new TableColumn(table, SWT.NULL); column2.setText(AntLaunchConfigurationMessages.AntTargetsTab_Description_6); // TableLayout only sizes columns once. If showing the targets // tab as the initial tab, the dialog isn't open when the layout // occurs and the column size isn't computed correctly. Need to // recompute the size of the columns once all the parent controls // have been created/sized. // HACK Bug 139190 getShell().addShellListener(new ShellAdapter() { @Override public void shellActivated(ShellEvent e) { if (!table.isDisposed()) { int tableWidth = table.getSize().x; if (tableWidth > 0) { int c1 = tableWidth / 3; column1.setWidth(c1); column2.setWidth(tableWidth - c1); } getShell().removeShellListener(this); } } }); fTableViewer = new CheckboxTableViewer(table); fTableViewer.setLabelProvider(new TargetTableLabelProvider()); fTableViewer.setContentProvider(new AntModelContentProvider()); fTableViewer.setComparator(new AntTargetsComparator()); fTableViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (!selection.isEmpty() && selection instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) selection; Object element = ss.getFirstElement(); boolean checked = !fTableViewer.getChecked(element); fTableViewer.setChecked(element, checked); updateOrderedTargets(element, checked); } } }); fTableViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { updateOrderedTargets(event.getElement(), event.getChecked()); } }); TableColumn[] columns = fTableViewer.getTable().getColumns(); for (int i = 0; i < columns.length; i++) { final int index = i; columns[index].addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (fSortButton.getSelection()) { // index 0 => sort_name (1) // index 1 => sort_description (2) int column = index + 1; if (column == fSortDirection) { column = -column; // invert the sort when the same column is selected twice in a row } setSort(column); } } }); } } /** * Return the number of rows available in the current display using the current font. * * @param parent * The Composite whose Font will be queried. * @return int The result of the display size divided by the font size. */ private int availableRows(Composite parent) { int fontHeight = (parent.getFont().getFontData())[0].getHeight(); int displayHeight = parent.getDisplay().getClientArea().height; return displayHeight / fontHeight; } /** * Updates the ordered targets list in response to an element being checked or unchecked. When the element is checked, it's added to the list. * When unchecked, it's removed. * * @param element * the element in question * @param checked * whether the element has been checked or unchecked */ private void updateOrderedTargets(Object element, boolean checked) { if (checked) { fOrderedTargets.add((AntTargetNode) element); } else { fOrderedTargets.remove(element); } updateSelectionCount(); updateLaunchConfigurationDialog(); } /** * Updates the selection count widget to display how many targets are selected (example, "1 out of 6 selected") and filtered. */ private void updateSelectionCount() { Object[] checked = fTableViewer.getCheckedElements(); String numSelected = Integer.toString(checked.length); int all = fAllTargets == null ? 0 : fAllTargets.length; int visible = fTableViewer.getTable().getItemCount(); String total = Integer.toString(visible); int numHidden = all - visible; if (numHidden > 0) { fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab_13, new Object[] { numSelected, String.valueOf(all), String.valueOf(numHidden) })); } else { fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab__0__out_of__1__selected_7, new Object[] { numSelected, total })); } fOrderButton.setEnabled(checked.length > 1); StringBuffer buffer = new StringBuffer(); Iterator<AntTargetNode> iter = fOrderedTargets.iterator(); while (iter.hasNext()) { buffer.append(iter.next().getTargetName()); buffer.append(", "); //$NON-NLS-1$ } if (buffer.length() > 2) { // remove trailing comma buffer.setLength(buffer.length() - 2); } fTargetOrderText.setText(buffer.toString()); } /** * Returns all targets in the buildfile. * * @return all targets in the buildfile */ private AntTargetNode[] getTargets() { if (fAllTargets == null || isDirty()) { fAllTargets = null; fDefaultTarget = null; setDirty(false); setErrorMessage(null); setMessage(null); final String expandedLocation = validateLocation(); if (expandedLocation == null) { return fAllTargets; } final CoreException[] exceptions = new CoreException[1]; try { IRunnableWithProgress operation = new IRunnableWithProgress() { /* * (non-Javadoc) * * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor) */ @Override public void run(IProgressMonitor monitor) { try { fAllTargets = AntUtil.getTargets(expandedLocation, fLaunchConfiguration); } catch (CoreException ce) { exceptions[0] = ce; } } }; IRunnableContext context = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (context == null) { context = getLaunchConfigurationDialog(); } ISchedulingRule rule = null; if (!ResourcesPlugin.getWorkspace().isTreeLocked()) { // only set a scheduling rule if not in a resource change callback rule = AntUtil.getFileForLocation(expandedLocation, null); } PlatformUI.getWorkbench().getProgressService().runInUI(context, operation, rule); } catch (InvocationTargetException e) { AntUIPlugin.log("Internal error occurred retrieving targets", e.getTargetException()); //$NON-NLS-1$ setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1); fAllTargets = null; return null; } catch (InterruptedException e) { AntUIPlugin.log("Internal error occurred retrieving targets", e); //$NON-NLS-1$ setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1); fAllTargets = null; return null; } if (exceptions[0] != null) { IStatus exceptionStatus = exceptions[0].getStatus(); IStatus[] children = exceptionStatus.getChildren(); StringBuffer message = new StringBuffer(exceptions[0].getMessage()); for (int i = 0; i < children.length; i++) { message.append(' '); IStatus childStatus = children[i]; message.append(childStatus.getMessage()); } setErrorMessage(message.toString()); fAllTargets = null; return fAllTargets; } if (fAllTargets == null) { // if an error was not thrown during parsing then having no targets is valid (Ant 1.6.*) return fAllTargets; } AntTargetNode target = fAllTargets[0]; AntProjectNode projectNode = target.getProjectNode(); setErrorMessageFromNode(projectNode); for (int i = 0; i < fAllTargets.length; i++) { target = fAllTargets[i]; if (target.isDefaultTarget()) { fDefaultTarget = target; } setErrorMessageFromNode(target); } } return fAllTargets; } private void setErrorMessageFromNode(AntElementNode node) { if (getErrorMessage() != null) { return; } if (node.isErrorNode() || node.isWarningNode()) { String message = node.getProblemMessage(); if (message != null) { setErrorMessage(message); } else { setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_0); } } } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ @Override public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { // do nothing } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) */ @Override public void initializeFrom(ILaunchConfiguration configuration) { fInitializing = true; fLaunchConfiguration = configuration; fOrderedTargets = new ArrayList<>(); setErrorMessage(null); setMessage(null); setDirty(true); boolean hideInternal = false; try { hideInternal = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, false); } catch (CoreException e) { AntUIPlugin.log(e); } fFilterInternalTargets.setSelection(hideInternal); handleFilterTargetsSelected(); int sort = SORT_NONE; try { sort = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, sort); } catch (CoreException e) { AntUIPlugin.log(e); } fSortButton.setSelection(sort != SORT_NONE); setSort(sort); String configTargets = null; String newLocation = null; try { configTargets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null); newLocation = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); } catch (CoreException ce) { AntUIPlugin.log(AntLaunchConfigurationMessages.AntTargetsTab_Error_reading_configuration_12, ce); } if (newLocation == null) { fAllTargets = null; initializeForNoTargets(); return; } AntTargetNode[] allTargetNodes = getTargets(); if (allTargetNodes == null) { initializeForNoTargets(); return; } String[] targetNames = AntUtil.parseRunTargets(configTargets); if (targetNames.length == 0) { fTableViewer.setAllChecked(false); setExecuteInput(allTargetNodes); if (fDefaultTarget != null) { fOrderedTargets.add(fDefaultTarget); fTableViewer.setChecked(fDefaultTarget, true); updateSelectionCount(); updateLaunchConfigurationDialog(); } fInitializing = false; return; } setExecuteInput(allTargetNodes); fTableViewer.setAllChecked(false); for (int i = 0; i < targetNames.length; i++) { for (int j = 0; j < fAllTargets.length; j++) { if (targetNames[i].equals(fAllTargets[j].getTargetName())) { fOrderedTargets.add(fAllTargets[j]); fTableViewer.setChecked(fAllTargets[j], true); } } } updateSelectionCount(); fInitializing = false; } private void initializeForNoTargets() { setExecuteInput(new AntTargetNode[0]); fTableViewer.setInput(new AntTargetNode[0]); fInitializing = false; } /** * Sets the execute table's input to the given input. */ private void setExecuteInput(Object input) { fTableViewer.setInput(input); updateSelectionCount(); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { // attribute added in 3.0, so null must be used instead of false for backwards compatibility if (fFilterInternalTargets.getSelection()) { configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, true); } else { configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, (String) null); } // attribute added in 3.0, so null must be used instead of 0 for backwards compatibility if (fSortDirection != SORT_NONE) { configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, fSortDirection); } else { configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, (String) null); } if (fOrderedTargets.size() == 1) { AntTargetNode item = fOrderedTargets.get(0); if (item.isDefaultTarget()) { configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null); return; } } else if (fOrderedTargets.size() == 0) { configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null); return; } StringBuffer buff = new StringBuffer(); Iterator<AntTargetNode> iter = fOrderedTargets.iterator(); String targets = null; while (iter.hasNext()) { AntTargetNode item = iter.next(); buff.append(item.getTargetName()); buff.append(','); } if (buff.length() > 0) { targets = buff.toString(); } configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, targets); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() */ @Override public String getName() { return AntLaunchConfigurationMessages.AntTargetsTab_Tar_gets_14; } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() */ @Override public Image getImage() { return AntUIImages.getImage(IAntUIConstants.IMG_TAB_ANT_TARGETS); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration) */ @Override public boolean isValid(ILaunchConfiguration launchConfig) { if (fAllTargets == null || isDirty()) { if (getErrorMessage() != null && !isDirty()) { // error in parsing; return false; } // targets not up to date and no error message...we have not parsed recently initializeFrom(launchConfig); if (getErrorMessage() != null) { // error in parsing; return false; } } setErrorMessage(null); return super.isValid(launchConfig); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#setDirty(boolean) */ @Override protected void setDirty(boolean dirty) { // provide package visibility super.setDirty(dirty); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ @Override public void activated(ILaunchConfigurationWorkingCopy workingCopy) { if (isDirty()) { super.activated(workingCopy); } } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ @Override public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) { if (fOrderedTargets.size() == 0) { // set the dirty flag so that the state will be reinitialized on activation setDirty(true); } } private String validateLocation() { String expandedLocation = null; String location = null; IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); try { location = fLaunchConfiguration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); if (location == null) { return null; } expandedLocation = manager.performStringSubstitution(location); if (expandedLocation == null) { return null; } File file = new File(expandedLocation); if (!file.exists()) { setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_15); return null; } if (!file.isFile()) { setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_16); return null; } return expandedLocation; } catch (CoreException e1) { if (location != null) { try { manager.validateStringVariables(location); setMessage(AntLaunchConfigurationMessages.AntTargetsTab_17); return null; } catch (CoreException e2) {// invalid variable setErrorMessage(e2.getStatus().getMessage()); return null; } } setErrorMessage(e1.getStatus().getMessage()); return null; } } protected boolean isTargetSelected() { return !fOrderedTargets.isEmpty(); } }